# fisher_test/api_new.py
import frappe
import requests
import json
from frappe import _


def get_po_by_wechat_user(wechat_userid, po_name=None):
    """
    根据微信用户ID获取采购订单数据
    如果指定了po_name，则获取特定PO；否则获取下一个待确认的PO
    """
    try:
        # 根据微信用户ID找到对应的供应商
        supplier = get_supplier_by_wechat_user(wechat_userid)
        if not supplier:
            frappe.log_error(f"未找到微信用户 {wechat_userid} 对应的供应商")
            return None
        
        if po_name:
            # 获取特定PO
            return get_specific_po(po_name, supplier)
        else:
            # 获取下一个待确认的PO
            pending_pos = get_pending_pos_for_supplier(supplier, limit=1)
            if pending_pos:
                return get_po_with_items(pending_pos[0].name)
            return None
            
    except Exception as e:
        frappe.log_error(f"获取采购订单失败: {str(e)}")
        return None


def get_specific_po(po_name, supplier):
    """获取特定的采购订单"""
    try:
        # 验证PO是否存在且属于该供应商
        po = frappe.get_doc("Purchase Order", po_name)
        
        if po.supplier != supplier:
            frappe.log_error(f"采购订单 {po_name} 不属于供应商 {supplier}")
            return None
        
        if po.status == "Closed":
            return None
            
        return get_po_with_items(po_name)
        
    except Exception as e:
        frappe.log_error(f"获取特定PO失败 {po_name}: {str(e)}")
        return None


def get_supplier_by_wechat_user(wechat_userid):
    """根据微信用户ID获取供应商"""
    try:
        wxwork_user = frappe.qb.DocType("WXWork User")
        portal_user = frappe.qb.DocType("Portal User")

        data = frappe.qb.from_(wxwork_user
        ).join(portal_user
        ).on(
            (wxwork_user.user == portal_user.user) &
            (wxwork_user.active == 1) &
            (portal_user.parenttype == "Supplier")
        ).where(
            wxwork_user.userid == wechat_userid
        ).select(
            portal_user.parent
        ).run()

        return data[0][0] if data else None
    except Exception as e:
        frappe.log_error(f"获取供应商失败: {str(e)}")
        return None


def get_pending_pos_for_supplier(supplier, limit=None):
    """获取供应商待确认的采购订单"""
    try:
        # 先找到有未确认交货日期物料的PO
        po_items = frappe.get_all(
            "Purchase Order Item",
            filters={
                "expected_delivery_date": ("is", "not set"),
                "schedule_date": ("is", "set")
            },
            fields=["parent"],
            group_by="parent"
        )
        
        if not po_items:
            return []
            
        po_names = [item.parent for item in po_items]
        
        # 再过滤属于该供应商且状态正确的PO
        filters = {
            "name": ["in", po_names],
            "supplier": supplier,
            "docstatus": 1,
            "status": ["in", ["To Receive and Bill", "To Receive"]]
        }
        
        fields = ["name", "supplier", "supplier_name", "transaction_date"]
        
        pos = frappe.get_all(
            "Purchase Order",
            filters=filters,
            fields=fields,
            order_by="transaction_date asc",
            limit=limit
        )
        
        return pos
    except Exception as e:
        frappe.log_error(f"获取待确认PO失败: {str(e)}")
        return []


def get_po_with_items(po_name):
    """获取采购订单及物料明细"""
    try:
        po = frappe.get_doc("Purchase Order", po_name)
        
        # 只返回需要确认的物料（有要求日期但未确认交货日期的）
        items_data = []
        for item in po.items:
            if not item.expected_delivery_date and item.schedule_date:
                items_data.append({
                    "name": item.name,
                    "item_code": item.item_code,
                    "item_name": item.item_name,
                    "qty": item.qty,
                    "schedule_date": item.schedule_date,
                    "expected_delivery_date": item.expected_delivery_date
                })
        
        # 如果没有需要确认的物料，返回None
        if not items_data:
            return None
        
        return {
            "name": po.name,
            "supplier_name": po.supplier_name,
            "transaction_date": po.transaction_date,
            "items": items_data
        }
    except Exception as e:
        frappe.log_error(f"获取PO详情失败 {po_name}: {str(e)}")
        return None


@frappe.whitelist(allow_guest=True)
def get_po_data_by_wechat(wechat_userid, po_name=None):
    """
    供前端调用的获取PO数据的API
    """
    try:
        frappe.logger().info(f"调用get_po_data_by_wechat: wechat_userid={wechat_userid}, po_name={po_name}")
        
        po_data = get_po_by_wechat_user(wechat_userid, po_name)
        
        if po_data:
            frappe.logger().info(f"成功找到PO: {po_data['name']}")
            return {
                "success": True,
                "po_data": po_data
            }
        else:
            message = "未找到指定采购订单" if po_name else "暂无待确认的采购订单"
            frappe.logger().info(f"未找到PO: {message}")
            return {
                "success": False,
                "message": message
            }
            
    except Exception as e:
        frappe.log_error(f"获取PO数据API失败: {str(e)}")
        return {
            "success": False,
            "message": str(e)
        }


@frappe.whitelist(allow_guest=True)
def get_po_by_name(po_name):
    """根据PO名称获取PO数据（用于刷新）"""
    try:
        return get_po_with_items(po_name)
    except Exception as e:
        frappe.log_error(f"获取PO失败 {po_name}: {str(e)}")
        return None


@frappe.whitelist(allow_guest=True)
def get_next_po_by_wechat(wechat_userid):
    """获取下一个待确认的PO"""
    try:
        supplier = get_supplier_by_wechat_user(wechat_userid)
        if not supplier:
            return {"success": False, "message": "未找到绑定的供应商"}
        
        # 获取所有待确认的订单
        pos = get_pending_pos_for_supplier(supplier)
        
        if not pos or len(pos) <= 1:
            return {"success": False, "message": "没有更多待确认的采购订单"}
        
        # 返回第二个订单（跳过第一个）
        po_data = get_po_with_items(pos[1].name)
        
        if not po_data:
            return {"success": False, "message": "没有更多待确认的采购订单"}
        
        return {"success": True, "po_data": po_data}
    except Exception as e:
        frappe.log_error(f"获取下一个PO失败: {str(e)}")
        return {"success": False, "message": str(e)}


@frappe.whitelist(allow_guest=True)
def confirm_delivery_date(wechat_userid=None, items=None):
    """
    更新采购订单 (Purchase Order) 中物料行的供应商确认交期 (expected_delivery_date)，
    并确保记录变更历史和更新 modified 时间戳。
    
    参数:
        wechat_userid (str): 微信用户ID，用于确定操作用户。
        items (list/str): 包含要更新的物料行数据的列表 (row_name, date, po_name)。
    """
    
    # 1. 数据解析和校验
    items = json.loads(items) if isinstance(items, str) else items
    
    if not items:
        frappe.throw(_("没有可确认的交期数据。"))

    po_name = items[0].get('po_name')
    if not po_name:
        frappe.throw(_("缺少采购订单名称。"))
        
    # 2. 确定操作用户和权限 (关键步骤)
    # 通过微信用户ID找到系统中的 User Name
    user = frappe.db.get_value("WXWork User", {"userid": wechat_userid, "active": 1}, "user")
    if not user:
        frappe.throw(_("未找到关联的系统用户。"))
    
    # 使用 set_user 确保后续操作（如 db_update）记录的操作者是正确的用户
    frappe.set_user(user)

    # 3. 获取并修改主单据
    try:
        # 使用 frappe.get_doc 获取完整的 Purchase Order 单据
        doc = frappe.get_doc("Purchase Order", po_name)
    except frappe.DoesNotExistError:
        frappe.throw(_(f"采购订单 {po_name} 不存在。"))
    except Exception as e:
        frappe.throw(_(f"获取采购订单失败: {e}"))

    updated_rows = set()
    
    # 建立一个以 row_name 为键的交期字典，方便快速查找
    date_map = {item["row_name"]: item["date"] for item in items}

    # 遍历 Purchase Order 中的所有子表行 (items)
    for row in doc.items:
        row_name = row.name
        if row_name in date_map:
            new_date = date_map[row_name]
            
            # 只有当日期有变化时才更新
            if str(row.expected_delivery_date) != str(new_date):
                row.expected_delivery_date = new_date
                updated_rows.add(row.item_code)

    if not updated_rows:
        # 如果没有实际修改任何交期，避免调用 db_update
        return "success"
    
    # 4. 调用 db_update 记录变更历史和更新时间戳
    # 使用 db_update 而不是 save/submit，以保持文档状态不变，但记录修改
    #doc.save() #要求交期是提交后可修改字段，但外部网站用户无权限
    #doc.save_version()
    doc.db_update_all()
    frappe.db.set_value(doc.doctype, doc.name, "modified", frappe.utils.now())
    
    # 5. 添加评论 (保持原逻辑，但现在操作者是正确的用户)
    comment_content = f"供应商确认交货日期已更新：{', '.join(list(updated_rows)[:5])}{'...' if len(updated_rows) > 5 else ''}"
    frappe.get_doc({
        "doctype": "Comment",
        "comment_type": "Comment", 
        "comment_by": user,  # 操作用户已通过 frappe.set_user(user) 设定
        "reference_doctype": "Purchase Order",
        "reference_name": po_name,
        "content": comment_content,
    }).insert(ignore_permissions=True)
    
    return "success"